#ifndef  FRAME_IMPL_H
#define  FRAME_IMPL_H


#include <memory>
#include <string>

namespace frame {

class IChannel;

class IReadBufferImpl {
public:
    typedef std::shared_ptr<IReadBufferImpl> Ptr;

    virtual ~IReadBufferImpl(){}

    virtual void * buffer() const = 0;
    virtual size_t freeBytes() const = 0;
	virtual size_t fakePut(size_t bytes) { return 0;}
};

class IWriteBufferImpl {
public:
    typedef std::shared_ptr<IWriteBufferImpl> Ptr;

    virtual ~IWriteBufferImpl(){}
    virtual const void * data() const = 0;
    virtual size_t inBytes() const = 0;
	virtual size_t fakeGet(size_t bytes) { return 0; };
};


class ChannelHandlerImpl;
class ChannelImpl{
public:
    typedef std::shared_ptr<ChannelImpl> Ptr;
    virtual ~ChannelImpl() {}

    virtual int open() = 0; //for some special init
    virtual int close() = 0; //for clear open resource

    virtual int read(IReadBufferImpl::Ptr buffer) = 0;
    virtual int write(IWriteBufferImpl::Ptr buffer) = 0;

    virtual int disconnect() = 0;

    virtual std::shared_ptr<ChannelHandlerImpl> getHandlerImpl() const = 0;
};

class ConnectHandlerImpl {
public:
    typedef std::shared_ptr<ConnectHandlerImpl> Ptr;
    virtual ~ConnectHandlerImpl(){}

    virtual void connected(ChannelImpl::Ptr channelImp) = 0;
    virtual void connectFailed(ChannelImpl::Ptr channelImp, int error) = 0;
};

class ChannelHandlerImpl {
public:
    typedef std::shared_ptr<ChannelHandlerImpl> Ptr;
    virtual ~ChannelHandlerImpl(){}

    virtual void disconnected(ChannelImpl::Ptr channel, int error) = 0;

    virtual void read(ChannelImpl::Ptr channel, const char * buf,  std::size_t size) = 0;
    virtual void readException(ChannelImpl::Ptr channel, int error) = 0 ;

    virtual void writed(ChannelImpl::Ptr channel, std::size_t size) = 0 ;
    virtual void writeException(ChannelImpl::Ptr channel, int error) = 0;

};

class ClientImpl {
public:
    typedef std::shared_ptr<ClientImpl> Ptr;

    virtual ~ClientImpl(){}

    virtual ChannelImpl::Ptr connect(const std::string & remoteIp, const int port, std::shared_ptr<ChannelHandlerImpl> channelHandlerImpl) = 0;

    virtual int open() = 0;
    virtual int close() = 0;
};

class ServiceImpl {
public:
    typedef std::shared_ptr<ServiceImpl> Ptr;

    virtual ~ServiceImpl(){}
    virtual int start() = 0;
    virtual int run() = 0;
    virtual void stop() = 0;
};

} //end of namespace frame

#endif   /* FRAME_IMPL_H */
